
#include "bootpack.h"


//初始化gdt idt
void init_gdtidt(void)
{
	 SEGMENT_DESCRIPTOR *gdt = ( SEGMENT_DESCRIPTOR *) ADR_GDT;
	 GATE_DESCRIPTOR    *idt = ( GATE_DESCRIPTOR    *) ADR_IDT;
	int i;

	/* GDT初始化 */
	for (i = 0; i <= LIMIT_GDT / 8; i++) {
		set_segmdesc(gdt + i, 0, 0, 0);
	}
	set_segmdesc(gdt + 1, 0xffffffff,   0x00000000, AR_DATA32_RW);
	set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER);
	set_gdtr(LIMIT_GDT, ADR_GDT);  //给gdtr设值 ，告诉CPU(gdtr)我的IDT的地址和容量 ,这时GDT开始起作用

	/* IDT初始化 */
	for (i = 0; i <= LIMIT_IDT / 8; i++) {
		set_gatedesc(idt + i, 0, 0, 0);
	}
	set_idtr(LIMIT_IDT, ADR_IDT); //告诉CPU我的IDT的地址和容量 ,这时IDT开始起作用 ，我可以注册中断响应函数了
	
	set_gatedesc(idt+ 0x0d,(int) asm_handler_int0d ,2<<3,AR_INTGATE32) ;//异常处理 
	set_gatedesc(idt+ 0x20,(int) asm_handler_int20 ,2<<3,AR_INTGATE32) ;//Timer 
	set_gatedesc(idt+ 0x21,(int) asm_handler_int21 ,2<<3,AR_INTGATE32) ;//键盘IRQ1
	set_gatedesc(idt+ 0x27,(int) asm_handler_int27 ,2<<3,AR_INTGATE32) ;//PIC初始化调用IRQ7
	set_gatedesc(idt+ 0x2c,(int) asm_handler_int2c ,2<<3,AR_INTGATE32) ;//鼠标IRQ12

	set_gatedesc(idt+ 0x40,(int) asm_api_main ,2<<3,AR_INTGATE32 +0x60) ;//api中断  ,不加上0x60时，任何调用api的方法会被保护机制禁止 ，发生中断
	return;
}
/* sd : gdt数据指针  
   limit:段大小
   base:段地址
   ar:权限
*/
void set_segmdesc( SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar)
{
	if (limit > 0xfffff) {
		ar |= 0x8000; /* G_bit = 1 */
		limit /= 0x1000;
	}
	sd->limit_low    = limit & 0xffff;
	sd->base_low     = base & 0xffff;
	sd->base_mid     = (base >> 16) & 0xff;
	sd->access_right = ar & 0xff;
	sd->limit_high   = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0);
	sd->base_high    = (base >> 24) & 0xff;
	return;
}
/**
	gd : idt数据指针
	offset:handler指针
	selector:段号  ，如果是第二个段 该数据应该为2<<3  因为ss低3位有别的用处
*/
void set_gatedesc( GATE_DESCRIPTOR *gd, int offset, int selector, int ar)
{
	gd->offset_low   = offset & 0xffff;
	gd->selector     = selector;
	gd->dw_count     = (ar >> 8) & 0xff;
	gd->access_right = ar & 0xff;
	gd->offset_high  = (offset >> 16) & 0xffff;
	return;
}
   
   